home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 2 / MacMania 2.toast / Demo's / Tools&Utilities / Programming / Tools Plus 2.5 / Tools Plus 2.5 (C⁄C++ & Pascal) / User Manual / 14-System Polling (2 of 4) < prev    next >
Encoding:
Text File  |  1994-05-24  |  27.9 KB  |  424 lines  |  [TEXT/ttxt]

  1. Event Modifiers
  2. ```````````````
  3.   Tools Plus’s event modifier field provides information identical to that obtained directly from the Macintosh’s Event Manager.  To reiterate, the Modifiers field of the event record contains information about the position of the Caps Lock, Shift, Option, Command and Control keys at the time of the event, as well as the position of the mouse button.  This can be used, for example, to detect if the Command key was down when a key was typed (i.e. a Command-key sequence).  In effect, your application could respond to command key sequences that are not menu equivalents by using this method.  Your application could also place special significance on Option-Clicks.  The most common use, however, is Shift-Tab that indicates that the user wants to tab to the previous field.
  4.  
  5.   In the Macintosh’s Event Manager, the Modifiers field of the event record is an integer.  Several of the bits indicate the state of the various modifiers, as detailed in Inside Macintosh Vol 1 and Vol 5.  Tools Plus goes a step further and automatically decodes individual modifiers in the field.  This is handled through a union in C, and a variant record in Pascal.
  6.  
  7.  
  8.  
  9.  
  10.  
  11. Event Modifiers Using C
  12. ```````````````````````
  13.   When programming in C, Tools Plus’s Modifiers structure is a union that lets you access both the integer obtained from the Macintosh’s Event Manager, as well as the individual flags (bits) within the integer.  Tools Plus’s Modifiers structure looks like this:
  14.  
  15.   union TPModifiersRec {             /*This variable record contains  */
  16.                                      /*  an event's "modifiers" in 2  */
  17.                                      /*  formats…                     */
  18.                                      /*  • Macintosh Event:           */
  19.     short Num;                       /*      integer (bit operations  */
  20.                                      /*      required)                */
  21.                                      /*  • Modifier integer parsed    */
  22.     struct {                         /*    into components:           */
  23.       unsigned short bit15 :1;       /* (reserved bit)                */
  24.       unsigned short bit14 :1;       /* (reserved bit)                */
  25.       unsigned short bit13 :1;       /* (reserved bit)                */
  26.       unsigned short ControlKey :1;  /* Control key was down at event */
  27.       unsigned short OptionKey :1;   /* Option key was down at event  */
  28.       unsigned short CapsLock :1;    /* Caps Lock was down at event   */
  29.       unsigned short ShiftKey :1;    /* Shift key was down at event   */
  30.       unsigned short CmdKey :1;      /* Command key was down at event */
  31.       unsigned short MouseUp :1;     /* Mouse button was UP at event  */
  32.       unsigned short bit6 :1;        /* (reserved bit)                */
  33.       unsigned short bit5 :1;        /* (reserved bit)                */
  34.       unsigned short bit4 :1;        /* (reserved bit)                */
  35.       unsigned short bit3 :1;        /* (reserved bit)                */
  36.       unsigned short bit2 :1;        /* (reserved bit)                */
  37.       unsigned short bit1 :1;        /* (reserved bit)                */
  38.       unsigned short bit0 :1;        /* (reserved bit)                */
  39.     } Bits;                          /*                               */
  40.   };
  41.   typedef union TPModifiersRec TPModifiersRec;
  42.  
  43.  
  44.   Whenever you access any of the individual modifier flags, you reference the “bits” part of the structure.  For example, if you want to check if the Command key was down and the Option key was up when a key was typed, you can use an expression such as this:
  45.  
  46.   if ((Poll.Modifiers.Bits.CmdKey) && (!Poll.Modifiers.Bits.OptionKey))
  47.  
  48.   In contrast, the Modifiers field provided by the Macintosh’s Event Manager requires bitwise “And” operations to determine if a bit is set or not, thereby resulting in source code that looks more cryptic.  The following line duplicates the previous example’s functionality using bitwise “And” operations instead of the available bits:
  49.  
  50.  if ((Poll.Modifiers.Num & cmdKey) && !(Poll.Modifiers.Num & optionKey))
  51.  
  52.   When you are working with the Modifiers structure, you may perform operations exclusively on the integer variant of the structure, on the bits variant, or if you choose, you can mix and match as needed.  Several constants representing the “bit-equivalents” for the various flags contained in the Modifiers integer are available as follows:
  53.  
  54.                             /*Modifier masks                        */
  55.  #define btnState   0x0080  /*set to 1 if mouse button is up        */
  56.  #define cmdKey     0x0100  /*set to 1 if Command key is down       */
  57.  #define shiftKey   0x0200  /*set to 1 if Shift key is down         */
  58.  #define alphaLock  0x0400  /*set to 1 if the Caps Lock key is down */
  59.  #define optionKey  0x0800  /*set to 1 if the option key is down    */
  60.  #define controlKey 0x1000  /*set to 1 if the control key is down   */
  61.  
  62.  
  63.  
  64.  
  65.  
  66. Event Modifiers Using Pascal
  67. ````````````````````````````
  68. When programming in Pascal, Tools Plus’s Modifiers structure is a variant record that lets you access both the integer obtained from the Macintosh’s Event Manager, as well as the individual flags (bits) within the integer.  Tools Plus’s Modifiers record looks like this:
  69.  
  70. {= Polling record's "event modifiers" info}
  71.   TPModifiersRec = packed record       {This variable record contains  }
  72.                                        {  an event's "modifiers" in 2  }
  73.     case integer of                    {  formats…                     }
  74.       0: (                             {  • Macintosh Event:           }
  75.         Num: integer                   {      integer (bit operations  }
  76.       );                               {      required)                }
  77.       1: (                             {  • Modifier integer parsed    }
  78.                                        {    into components:           }
  79.         bit15, bit14, bit13: boolean;  { (reserved bits)               }
  80.         ControlKey: boolean;           { Control key was down at event }
  81.         OptionKey: boolean;            { Option key was down at event  }
  82.         CapsLock: boolean;             { Caps Lock was down at event   }
  83.         ShiftKey: boolean;             { Shift key was down at event   }
  84.         CmdKey: boolean;               { Command key was down at event }
  85.         MouseUp: boolean;              { Mouse button was UP at event  }
  86.         bit6, bit5, bit4, bit3, bit2,  { (reserved bits)               }
  87.         bit1,bit0: boolean;            {                               }
  88.       );                               {                               }
  89.     end;
  90.  
  91.  
  92.   You use each field in the record as an individual modifier variable.  For example, if you want to check if the Command key was down and the Option key was up when a key was typed, you can use an expression such as this:
  93.  
  94.      if Poll.Modifiers.CmdKey and not Poll.Modifiers.OptionKey then
  95.  
  96.   In contrast, the Modifiers field provided by the Macintosh’s Event Manager requires bitwise “And” operations to determine if a bit is set or not, thereby resulting in source code that looks more cryptic.  The following line duplicates the previous example’s functionality using bitwise “And” operations instead of the available bits:
  97.  
  98.     if (BitAnd(Poll.Modifiers.Num,cmdKey) <> 0) and
  99.                       BitAnd(Poll.Modifiers.Num,optionKey) = 0) then
  100.  
  101.   When you are working with the Modifiers record, you may perform operations exclusively on the integer variant of the record, on the bits variant, or if you choose, you can mix and match as needed.  Several constants representing the “bit-equivalents” for the various flags contained in the Modifiers integer are available as follows:
  102.  
  103. CONST                        {Modifier masks                        }
  104.           btnState  =$0080;  {set to 1 if mouse button is up        }
  105.           cmdKey    =$0100;  {set to 1 if Command key is down       }
  106.           shiftKey  =$0200;  {set to 1 if Shift key is down         }
  107.           alphaLock =$0400;  {set to 1 if the Caps Lock key is down }
  108.           optionKey =$0800;  {set to 1 if the option key is down    }
  109.           controlKey=$1000;  {set to 1 if the control key is down   }
  110.  
  111. ------------------------------------------------------------------------
  112.  
  113. PollSystem
  114. ``````````
  115.   Determine if an event occurred, and obtain that event.  PollSystem also keeps Tools Plus’s automatic processes running.
  116.  
  117.    pascal Boolean PollSystem (TPPollRecord *Poll);
  118.  
  119.    function PollSystem(var Poll:TPPollRecord): BOOLEAN;
  120.  
  121.   The Poll record contains all the information about an event.
  122.  
  123.   The function’s value returns true if an event was obtained, and false if an event was not obtained.  When PollSystem returns false, it is called a “null” event, or in Tools Plus terminology, a doNothing event.
  124.  
  125.   PollSystem calls the Macintosh Event Manager’s WaitNextEvent function (or GetNextEvent function) which performs all necessary task switching and background processing control.  Desk Accessories’ get their events, and other applications that are also running under MultiFinder or System 7 get some processing time.
  126.  
  127.   If your application does “background processing,” that is, it performs an on-going process while it is waiting for events, it should perform “one cycle” of its background process each time it receives a doNothing event (when PollSystem returns false).  A single cycle of your application’s background process should take no longer than 1/60 of a second.  See the SetNullTime routine to set the interval at which your application receives doNothing events.
  128.  
  129.   PollSystem should be called as often as possible (at least sixty times per second) to keep desk accessories, automatic processes, and other applications running under MultiFinder or System 7 running smoothly.  It is important that your application does not do a lot of processing between calls to PollSystem or it will be a “CPU hog” and make other applications run sluggishly or in spurts and jumps.
  130.  
  131. Also see:  SetNullTime.
  132.  
  133. Note: Your application should call PollSystem as often as possible (at
  134.       least 60 times per second) to allow other applications adequate
  135.       processing time.
  136.  
  137. Warning: Do not call PollSystem from within a BeginUpdateScreen /
  138.          EndUpdateScreen structure.
  139.  
  140.  
  141.  
  142.  
  143.  
  144. Tools Plus Event Codes
  145. ``````````````````````
  146.   Each event reported by PollSystem is identified by the first field of the polling record, Poll.What.  The Poll.What field contains an event code that tells your application what to do with the event record’s information.  Constants are used to identify event codes as follows:
  147.  
  148.   CONST                   {Tools Plus event codes                 }
  149.     doNothing     =  0;   {no event                               }
  150.     doChgWindow   =  1;   {user clicked in an inactive window     }
  151.     doRefresh     =  2;   {a window has to be refreshed           }
  152.     doGoAway      =  3;   {the Go-Away box was clicked            }
  153.     doButton      =  4;   {button was clicked                     }
  154.     doMenu        =  5;   {menu was selected                      }
  155.     doKeyDown     =  6;   {a keyboard key was pressed             }
  156.     doAutoKey     =  7;   {a keyboard key is auto-repeating       }
  157.     doKeyUp       =  8;   {a keyboard key was released            }
  158.     doClickField  =  9;   {mouse clicked in inactive editing field}
  159.     doScrollBar   = 10;   {mouse clicked in a scroll bar          }
  160.     doListBox     = 11;   {some sort of List Box activity         }
  161.     doClick       = 12;   {mouse click/drag [1..3]                }
  162.     doPopUpMenu   = 13;   {pop-up menu was selected               }
  163.     doPictButton  = 14;   {picture button activity                }
  164.     doClickControl=101;   {mouse clicked in a custom control      }
  165.     doManualEvent =102;   {manually processed events              }
  166.     doMoveWindow  =103;   {a window was moved by user             }
  167.     doGrowWindow  =104;   {a window was “grown” by user           }
  168.     doClickDesk   =105;   {mouse clicked in the desk top          }
  169.     doZoomWindow  =106;   {zoom box was clicked by user           }
  170.     doSuspend     =107;   {appl. suspended (in background)        }
  171.     doResume      =108;   {appl. resumed (now active appl.)       }
  172.  
  173.   Event codes over 100 will likely be ignored by most applications.  All events are detailed later, telling you how to respond to the event and which fields in the event record contain valid information that is related to the event.
  174.  
  175.  
  176.  
  177.  
  178.  
  179. What Does PollSystem Do?
  180. ````````````````````````
  181.   On the surface, it appears that PollSystem is just a fancy way to get an event from the Toolbox Event Manager.  Quite to the contrary, PollSystem does a lot of work for you.
  182.  
  183.   The biggest service that PollSystem performs is to keep Tools Plus’s automatic processes running smoothly.  To do this, you must understand the difference between an internally processed event, and an externally processed event.
  184.  
  185.  
  186.  
  187.  
  188.  
  189. Internally Processed Events
  190. ```````````````````````````
  191.   An internal event is something that can be processed by Tools Plus without the knowledge or assistance of your application.  Hence the term internal means internal to Tools Plus.  The internal processing of events is how PollSystem drives its automatic tasks.
  192.  
  193.   An example of an internally processed event is a key-down event from the Toolbox Event Manager.  If the active window belongs to your application and it has an active editing field, the user’s key-strokes will affect the text in the editing field automatically.  Since this event is processed internally, no event is reported to your application.
  194.  
  195.   One of the tricks that PollSystem utilizes, is to process as many internal events as it possibly can before returning to your application.  It will return to your application when the event queue is empty, or when it encounters an event that cannot be processed internally.  Why doesn’t it process just one event at a time?  If your application is busy and the user types 10 characters on the keyboard before PollSystem is called, the single call to PollSystem will process all 10 keystrokes!  This ensures that Tools Plus’s automatic processes occur as smoothly as possible without accumulating a backlog of events.
  196.  
  197.  
  198.  
  199.  
  200.  
  201. Externally Processed Events
  202. ```````````````````````````
  203.   Whenever PollSystem encounters an event it cannot process internally, it reports the event to your application.  An example of this is when the user clicks the close box in the active window.  Your application may want to ask the user if he wants to save the changes before closing the document.  Therefore, PollSystem only reports a request to close a window, and does not actually close it.
  204.  
  205.   Some events may be ignored by your application.  One of these events tells your application that the user dragged a window.  Your application may be interested in a window’s co-ordinates at any given time, in which case this event would be crucial.  In most cases, applications don’t care if the window is dragged, and always ignore the event.
  206.  
  207.  
  208.  
  209.  
  210.  
  211. Inside PollSystem
  212. `````````````````
  213.   Inside PollSystem describes the inner workings of the PollSystem routine.  Those programmers who are curious about this aspect, or those that want to know how Toolbox Events are translated into Tools Plus events may find this passage interesting.
  214.  
  215.   Every time your application calls PollSystem, several things happen automatically:
  216.  
  217.    (1) Desk accessories and background processes are given some processing time.
  218.  
  219.    (2) The active desk accessory (if there is one) gets any events it requires.
  220.  
  221.    (3) The insertion point is kept blinking in the active editing field (if there is one).
  222.  
  223.    (4) Task switching occurs to give other applications some processing time (when using MultiFinder or System 7).
  224.  
  225.    (5) The event queue is checked for an event.  If any events exist, the first one is removed from the queue.  If the event can be processed internally by Tools Plus, it is and this step is repeated.
  226.  
  227.    (6) If an event is obtained that can not be processed internally by Tools Plus, then Tools Plus’s event record is populated with all the required information for that event in a format that is readily usable by your application.
  228.  
  229.    (7) The cursor’s position is checked and its shape is changed if required.
  230.  
  231.    (8) PollSystem returns to your application with an event, or a “no event” (false) status.
  232.  
  233.  
  234.  
  235.  
  236.  
  237. Translating Toolbox events to Tools Plus events
  238. ```````````````````````````````````````````````
  239.   Step 3 looks pretty simple when it is summarized in a couple lines, however, the recognition and processing of internal events is quite an extensive duty for Tools Plus.  The table below describes this formidable task by listing the Macintosh’s Toolbox Event Manager’s event, the internal processes that follow, and the event that finally reaches your application.  Remember that some Toolbox events are processed internally and never reach your application, and some events that reach your program can be ignored.
  240.  
  241.  
  242.  
  243. ============+=========================================+===============
  244. Toolbox’s   | Conditions and                          |  PollSystem’s
  245. Event       | Tools Plus’s Internal Processing        |      Event
  246. ============+=========================================+===============
  247. nullEvent   | none                                    | doNothing
  248. ------------+-----------------------------------------+---------------
  249. mouseDown   | If the watch cursor is displayed then   |
  250.             | the event is ignored (clicks in push    |
  251.             | buttons are optionally exempted)        |
  252.             |-----------------------------------------+---------------
  253.             | Outside of a modal window (beep)        |
  254.             |-----------------------------------------+---------------
  255.             | In an inactive window that belongs to   | doChgWindow
  256.             | your application                        |
  257.             |-----------------------------------------+---------------
  258.             | In a floating palette that is not the   | doRefresh
  259.             | front most palette, and is partially    |
  260.             | obscured by another palette.  After     |
  261.             | refreshing the window, the mouse-down   |
  262.             | event is processed.                     |
  263.             |-----------------------------------------+---------------
  264.             | In a floating palette’s title bar       |
  265.             |-----------------------------------------+---------------
  266.             | In an inactive window that belongs to   | doSuspend
  267.             | another application or desk accessory   |
  268.             |-----------------------------------------+---------------
  269.             | In Apple menu, except for “About…” item |
  270.             | (selected item is opened or activated)  |
  271.             |-----------------------------------------+---------------
  272.             | In Apple menu’s “About…” item           | doMenu
  273.             |-----------------------------------------+---------------
  274.             | In Edit menu’s Undo, Cut, Copy, Paste,  |
  275.             | or Clear item is selected for an active |
  276.             | editing field or active desk accessory  |
  277.             | (operation is done automatically)       |
  278.             |-----------------------------------------+---------------
  279.             | In other (pull-down or hierarchical)    | doMenu
  280.             | menu selection                          |
  281.             |-----------------------------------------+---------------
  282.             | In a pop-up menu                        | doPopUpMenu
  283.             |-----------------------------------------+---------------
  284.             | In an active desk accessory or other    |
  285.             | application (clicking, dragging, or     |
  286.             | closing, etc.)                          |
  287.             |-----------------------------------------+---------------
  288.             | Selecting or deselecting lines in a     | doListBox
  289.             | list box.                               |
  290.             |-----------------------------------------+---------------
  291.             | Button in the active window (only if    | doButton
  292.             | mouse was released inside the button’s  |
  293.             | area)                                   |
  294.             |-----------------------------------------+---------------
  295.             | Picture button in the active window:    | doPictButton
  296.             | buttons with the “repeating events”     |
  297.             | option turned on produce events while   |
  298.             | the picture button is held down, as long|
  299.             | as the button does not reach the end of |
  300.             | its range.  Those without the “repeating|
  301.             | events” option produce an event only if |
  302.             | mouse was released inside the button’s  |
  303.             | area.                                   |
  304.             |-----------------------------------------+---------------
  305.             | Scroll bar in the active window (while  | doScrollBar
  306.             | in up arrow, down arrow, Page up region,|
  307.             | or Page Down region, or if thumb was    |
  308.             | moved)                                  |
  309.             |-----------------------------------------+---------------
  310.             | Active editing field, when setting a    |
  311.             | new insertion point or selection range  |
  312.             | (Edit menu’s items are enabled/disabled |
  313.             | according to the insertion point or     |
  314.             | selection)                              |
  315.             |-----------------------------------------+---------------
  316.             | Inactive editing field                  | doClickField
  317.             |-----------------------------------------+---------------
  318.             | Single-click, double-click, triple-     | doClick
  319.             | click, and/or dragging                  |
  320.             |-----------------------------------------+---------------
  321.             | Active window is dragged by user        | doMoveWindow
  322.             |-----------------------------------------+---------------
  323.             | Active window’s size is changed by      | doGrowWindow
  324.             | using the size box                      |
  325.             |-----------------------------------------+---------------
  326.             | Active window’s close box was clicked   | doGoAway
  327.             |-----------------------------------------+---------------
  328.             | Active window’s “zoom box” was clicked  | doZoomWindow
  329.             |-----------------------------------------+---------------
  330.             | Custom control                          | doClickControl
  331.             |-----------------------------------------+---------------
  332.             | On the desk top                         | doClickDesk
  333. ------------+-----------------------------------------+---------------
  334. mouseUp     | none                                    |
  335. ------------+-----------------------------------------+---------------
  336. keyDown     | If the watch cursor is displayed then   |
  337. autoKey     | the event is ignored (except for        |
  338.             | Command-.)                              |
  339.             |-----------------------------------------+---------------
  340.             | Command key invoking Edit menu’s Undo,  |
  341.             | Cut, Copy, or Paste item in an active   |
  342.             | editing field, or an active desk        |
  343.             | accessory under Finder (the editing     |
  344.             | operation is done automatically)        |
  345.             |-----------------------------------------+---------------
  346.             | Command key invoking a menu             | doMenu
  347.             |-----------------------------------------+---------------
  348.             | Command key NOT invoking a menu         | doKeyDown or
  349.             |                                         | doAutoKey
  350.             |-----------------------------------------+---------------
  351.             | Enter or Return key invoking a default  | doButton
  352.             | push-button                             |
  353.             |-----------------------------------------+---------------
  354.             | Active editing field processing keys    |
  355.             | (Edit menu’s items are enabled/disabled |
  356.             | according to the selection in the       |
  357.             | editing field.  Undo item is changed    |
  358.             | according to field’s contents, such as  |
  359.             | “Undo Typing”)                          |
  360.             |-----------------------------------------+---------------
  361.             | Other key strokes                       | doKeyDown or
  362.             |                                         | doAutoKey
  363. ------------+-----------------------------------------+---------------
  364. keyUp       | If the watch cursor is displayed then   |
  365.             | the event is ignored                    |
  366.             |-----------------------------------------+---------------
  367.             | Active editing field ignores key up     |
  368.             | events                                  |
  369.             |-----------------------------------------+---------------
  370.             | Other key-ups, providing that           | doKeyUp
  371.             | SetEventMask has not masked out key up  |
  372.             | events                                  |
  373. ------------+-----------------------------------------+---------------
  374. updateEvt   | Buttons, scroll bars, custom controls,  | doRefresh
  375.             | editing fields, and list boxes are      |
  376.             | automatically redrawn (refreshed)       |
  377.             | whenever an obscured window is uncovered|
  378. ------------+-----------------------------------------+---------------
  379. activateEvt | When a window is deactivated, the       |
  380.             | following happens automatically:        |
  381.             | [1] text in the active editing field is |
  382.             | deselected and the insertion point is   |
  383.             | removed, [2] list box lines are         |
  384.             | deselected, [3] scroll bars are hidden, |
  385.             | [4] buttons are disabled, and [5] if the|
  386.             | window has a “grow box,” it is hidden.  |
  387.             | When the window is activated again, all |
  388.             | objects return to their normal state.   |
  389. ------------+-----------------------------------------+---------------
  390. diskEvt     | no internal processing                  | doManualEvent
  391. networkEvt  |                                         |
  392. driverEvt   |                                         |
  393. app1Evt     |                                         |
  394. app2Evt     |                                         |
  395. app3Evt     |                                         |
  396. kHighLevel- |                                         |
  397.   Evt       |                                         |
  398. ------------+-----------------------------------------+---------------
  399. app4Evt     | If your application’s SIZE resource is  | doManualEvent
  400. osEvt       | set to not respond to Suspend/Resume    |
  401.             | events, then no internal processing     |
  402.             | occurs.                                 |
  403.             |-----------------------------------------+---------------
  404.             | If your application’s SIZE resource is  | doSuspend or
  405.             | set to respond to Suspend/Resume events,| doResume
  406.             | then these event are reported to your   |
  407.             | application.  In System 7, the osEvt    |
  408.             | representing the “mouse moved” event.   |
  409.             |-----------------------------------------+---------------
  410.             | In System 7 the osEvt also carries the  |
  411.             | “mouse moved” status, thereby becoming a|
  412.             | “mouse moved event.”  Tools Plus uses   |
  413.             | these events to automatically change the|
  414.             | cursor’s shape.                         |
  415. ----------------------------------------------------------------------
  416.  
  417.  
  418.  
  419. Responding to Events
  420. ````````````````````
  421.   When PollSystem returns with a value of false, it indicates that no event has occurred.  This is commonly called a “null event” or a doNothing event in Tools Plus.  Usually, your application won’t do anything other than idle in the main event loop.  Applications that do on-going processing should do their work only when they receive a null event.
  422.  
  423.   PollSystem returns with a value of true when an event is available.  The first field in the polling record is “what,” which tells your application what type of event has occurred.  The following section of this chapter describes how your application should respond to each event.  It also details any programming considerations that should be taken into account when responding to such an event.
  424.